//
//  CloudClient.swift
//  home
//
//  Created by Yun Zeng on 2019/8/4.
//  Copyright © 2019 Yun Zeng. All rights reserved.
//

import Foundation

// MARK: 服务器地址
fileprivate let cloudWSURL = URL(string: "ws://adai.design:6666/member/ws")!

protocol CloudMessageHandler {
    func handle(msg: CloudMessage) -> CloudMessageError
    func clientStateChange(state: CloudClient.State)
}

extension CloudClient {
    static let instance = {
        return CloudClient(url: cloudWSURL)
    } ()
}

// 与服务器连接的客户端
class CloudClient {
    // 客户端的四中状态: 关闭 断开 正在登录 数据传输
    enum State: String {
        case disable
        case disconnect
        case verify
        case transfer
    }
    var state: State = .disable {
        didSet {
            for observer in self.observers {
                observer.value.clientStateChange(state: self.state)
            }
        }
    }

    var client: WebSocket
    var timer: Timer?
    
    private init(url: URL) {
        self.client = WebSocket(url: url)
        self.client.delegate = self
        self.client.pongDelegate = self
        
        // 断开重连与心跳维持
        self.timer = Timer.scheduledTimer(withTimeInterval: 3.0, repeats: true, block: { (time) in
            if self.state == .disable {
                return
            }
            if !self.client.isConnected {
                self.client.connect()
            } else {
                self.client.write(ping: "".data(using: .utf8)!)
            }
        })
    }
    
    func enable() {
        if !self.client.isConnected {
            self.state = .disconnect
            self.client.connect()
        }

    }
    
    func disable() {
        self.state = .disable
        if self.client.isConnected {
            self.client.disconnect()
        }
        self.timer?.fire()
    }
    
    private var observers = Dictionary<String, CloudMessageHandler>()
    public func addObserver(path: String, controller: CloudMessageHandler) -> Bool {
        self.observers[path] = controller
        return true
    }
    
    // MARK: 客户端收发消息
    func receiveMessage(msg: CloudMessage) {
        if msg.path != CloudMessage.Path.heartbeat {
            Logger.Debug("message <- " + msg.description)
        } else {
            return
        }
        if let path = msg.path.split(separator: "/").first {
            if let controller = self.observers[path.lowercased()] {
                _ = controller.handle(msg: msg)
                return
            }
        }
        Logger.Warning("unknown message: " + msg.description)
    }
    
    func sendMessage(msg: CloudMessage) {
        if self.client.isConnected {
            if msg.path != CloudMessage.Path.heartbeat {
                Logger.Debug("message -> " + msg.description)
            }
            if let data = msg.encode() {
                self.client.write(data: data)
            }
        }
    }
}

// MARK: Websocket回调
extension CloudClient: WebSocketDelegate, WebSocketPongDelegate {
    func websocketDidConnect(socket: WebSocket) {
        self.state = .verify
    }
    
    func websocketDidDisconnect(socket: WebSocket, error: NSError?) {
        if self.state != .disable {
            self.state = .disconnect
        }
    }
    
    func websocketDidReceiveMessage(socket: WebSocket, text: String) {
    }
    
    func websocketDidReceiveData(socket: WebSocket, data: Data) {
        guard let msg = CloudMessage(data: data) else {
            Logger.Error("invalid-data: \(String(data: data, encoding: .utf8)!)")
            return
        }
        self.receiveMessage(msg: msg)
    }
    
    func websocketDidReceivePong(socket: WebSocket, data: Data?) {
    }
}






